package com.huatai.datacenter.entity;

/**
 * @program: ht-system
 * @description: 单数据查询
 * @author: songxiude
 * @create: 2023-04-25 14:11
 **/

import com.huatai.common.util.TimeUtil;
import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;

/**
 * @program: ht-system
 * @description: 查询
 * @author: songxiude
 * @create: 2023-04-25 16:56
 **/
@Data
public class QuerySingle {

	/**
	 * 查询开始时间
	 * 1. <amount><time unit>-ago
	 * 	  Eg: 1d-ago
	 * 2. LocalDateTime
	 * 3. Long 10 位数的时间戳
	 * 4. Double 10位整数 + 3位小数的时间戳
	 * 5.yyyy/MM/dd-HH:mm:ss
	 * 	 yyyy/MM/dd HH:mm:ss
	 * 	 yyyy/MM/dd-HH:mm
	 * 	 yyyy/MM/dd HH:mm
	 * 	 yyyy/MM/dd
	 *
	 */
	private String start;
	/**
	 * 查询结束时间
	 */
	private String end;
	/**
	 * 聚合方式
	 */
	private String aggregator = "";
	/**
	 * 下采样
	 * <amount><time unit> - sum avg min max first last - none null nan zero
	 * 时间-采样方式-补位
	 * 30m-min
	 * 30m-min-null
	 *
	 * ms - Milliseconds
	 * s - Seconds
	 * m - Minutes
	 * h - Hours
	 * d - Days (24 hours)
	 * w - Weeks (7 days)
	 * n - Months (30 days)
	 * y - Years (365 days)
	 *
	 */
	private String downSample;
	/**
	 * 采用下采样时,是否从元数据中获取值
	 * false :	从汇总表中获取		--> 	""
	 * true  :	从原始数据中获取 	--> 	"ROLLUP_RAW"
	 */
	private String rollupUsage;
	/**
	 * 设备编码
	 */
	@NotBlank
	private String equipCode;
	/**
	 * 量测编码
	 */
	@NotNull
	private String[] metrics;


	private String[] value;


	/**
	 * 是否是查询差值
	 * true 查询
	 */
	private boolean difference;

	public QuerySingle() {
	}

	public QuerySingle(LocalDateTime start, LocalDateTime end, String equipCode, String[] metrics) {
		check(start, end);
		this.downSample = "";
		this.equipCode = equipCode;
		this.metrics = metrics;
	}

	public QuerySingle(Long start, Long end, String equipCode, String[] metrics) {
		check(start, end);
		this.downSample = "";
		this.equipCode = equipCode;
		this.metrics = metrics;
	}

	public QuerySingle(Double start, Double end, String equipCode, String[] metrics) {
		check(start, end);
		this.downSample = "";
		this.equipCode = equipCode;
		this.metrics = metrics;
	}

	public QuerySingle(String start, String end, String equipCode, String[] metrics) {
		check(start, end);
		this.downSample = "";
		this.equipCode = equipCode;
		this.metrics = metrics;
	}

	public QuerySingle(LocalDateTime start, LocalDateTime end, String downSample, String equipCode, String[] metrics) {
		check(start, end);
		this.downSample = downSample;
		this.equipCode = equipCode;
		this.metrics = metrics;
	}
	public QuerySingle(Double start, Double end, String downSample, String equipCode, String[] metrics) {
		check(start, end);
		this.downSample = downSample;
		this.equipCode = equipCode;
		this.metrics = metrics;
	}
	public QuerySingle(Long start, Long end, String downSample, String equipCode, String[] metrics) {
		check(start, end);
		this.downSample = downSample;
		this.equipCode = equipCode;
		this.metrics = metrics;
	}
	public QuerySingle(String start, String end, String downSample, String equipCode, String[] metrics) {
		check(start, end);
		this.downSample = downSample;
		this.equipCode = equipCode;
		this.metrics = metrics;
	}

	public QuerySingle(LocalDateTime start, LocalDateTime end, String downSample, String equipCode, String metrics) {
		check(start, end);
		this.downSample = downSample;
		this.equipCode = equipCode;
		this.metrics = new String[]{metrics};
	}

	public QuerySingle(Double start, Double end, String downSample, String equipCode, String metrics) {
		check(start, end);
		this.downSample = downSample;
		this.equipCode = equipCode;
		this.metrics = new String[]{metrics};
	}

	public QuerySingle(Long start, Long end, String downSample, String equipCode, String metrics) {
		check(start, end);
		this.downSample = downSample;
		this.equipCode = equipCode;
		this.metrics = new String[]{metrics};
	}

	public QuerySingle(String start, String end, String downSample, String equipCode, String metrics) {
		check(start, end);
		this.downSample = downSample;
		this.equipCode = equipCode;
		this.metrics = new String[]{metrics};
	}

	public QuerySingle(LocalDateTime start, LocalDateTime end, String downSample, boolean rollupUsage, @NotBlank String equipCode, @NotNull String[] metrics) {
		check(start, end);
		this.downSample = downSample;
		if (rollupUsage) {
			this.rollupUsage = "ROLLUP_RAW";
		}
		this.equipCode = equipCode;
		this.metrics = metrics;
	}

	public QuerySingle(Long start, Long end, String downSample, boolean rollupUsage, @NotBlank String equipCode, @NotNull String[] metrics) {
		check(start, end);
		this.downSample = downSample;
		if (rollupUsage) {
			this.rollupUsage = "ROLLUP_RAW";
		}
		this.equipCode = equipCode;
		this.metrics = metrics;
	}

	public QuerySingle(Double start, Double end, String downSample, boolean rollupUsage, @NotBlank String equipCode, @NotNull String[] metrics) {
		check(start, end);
		this.downSample = downSample;
		if (rollupUsage) {
			this.rollupUsage = "ROLLUP_RAW";
		}
		this.equipCode = equipCode;
		this.metrics = metrics;
	}

	public QuerySingle(String start, String end, String downSample, boolean rollupUsage, @NotBlank String equipCode, @NotNull String[] metrics) {
		check(start, end);
		this.downSample = downSample;
		if (rollupUsage) {
			this.rollupUsage = "ROLLUP_RAW";
		}
		this.equipCode = equipCode;
		this.metrics = metrics;
	}

	public QuerySingle(LocalDateTime start, LocalDateTime end, String downSample, boolean rollupUsage, @NotBlank String equipCode, String metric) {
		check(start, end);
		this.downSample = downSample;
		if (rollupUsage) {
			this.rollupUsage = "ROLLUP_RAW";
		}
		this.equipCode = equipCode;
		this.metrics = new String[]{metric};
	}

	public QuerySingle(Long start, Long end, String downSample, boolean rollupUsage, @NotBlank String equipCode, String metric) {
		check(start, end);
		this.downSample = downSample;
		if (rollupUsage) {
			this.rollupUsage = "ROLLUP_RAW";
		}
		this.equipCode = equipCode;
		this.metrics = new String[]{metric};
	}

	public QuerySingle(Double start, Double end, String downSample, boolean rollupUsage, @NotBlank String equipCode, String metric) {
		check(start, end);
		this.downSample = downSample;
		if (rollupUsage) {
			this.rollupUsage = "ROLLUP_RAW";
		}
		this.equipCode = equipCode;
		this.metrics = new String[]{metric};
	}

	public QuerySingle(String start, String end, String downSample, boolean rollupUsage, @NotBlank String equipCode, String metric) {
		check(start, end);
		this.downSample = downSample;
		if (rollupUsage) {
			this.rollupUsage = "ROLLUP_RAW";
		}
		this.equipCode = equipCode;
		this.metrics = new String[]{metric};
	}

	private void check(Object start, Object end){
		// 如果是 LocalDateTime 类型
		if (start instanceof LocalDateTime) {
			this.start = TimeUtil.build((LocalDateTime) start).resultToSecond() + ".000";
		}
		if (end instanceof LocalDateTime) {
			this.end = TimeUtil.build((LocalDateTime) end).resultToSecond() + ".999";
		}
		// 如果是 Double 类型
		if (start instanceof Double) {
			this.start = String.format("%.3f", start);
		}
		if (end instanceof Double) {
			this.end = String.format("%.3f", end);
		}
		// 如果是 Long 类型
		if (start instanceof Long) {
			int length = String.valueOf(start).length();
			if (length == 10) {
				this.start = start + ".000";
			} else {
				this.start =  String.valueOf(start).substring(0, 9) + ".000";
			}
		}
		if (end instanceof Long) {
			int length = String.valueOf(end).length();
			if (length == 10) {
				this.end = end + ".999";
			} else {
				this.end =  String.valueOf(end).substring(0, 10) + ".999";
			}
		}
		// 如果是 String 类型
		if (start instanceof String) {
			this.start = (String) start;
		}
		if (end instanceof String) {
			this.end = (String) end;
		}
	}

}

